package com.ihr360.job.core.listener;

import com.ihr360.job.core.ExitStatus;
import com.ihr360.job.core.StepExecutionListener;
import com.ihr360.job.core.entity.StepExecution;
import org.springframework.core.Ordered;

import java.util.Arrays;
import java.util.Iterator;

public class CompositeStepExecutionListener  implements StepExecutionListener {
    private OrderedComposite<StepExecutionListener> list = new OrderedComposite<StepExecutionListener>();

    /**
     * Public setter for the listeners.
     *
     * @param listeners
     */
    public void setListeners(StepExecutionListener[] listeners) {
        list.setItems(Arrays.asList(listeners));
    }

    /**
     * Register additional listener.
     *
     * @param stepExecutionListener
     */
    public void register(StepExecutionListener stepExecutionListener) {
        list.add(stepExecutionListener);
    }

    /**
     * Call the registered listeners in reverse order, respecting and
     * prioritizing those that implement {@link Ordered}.
     * @see org.springframework.batch.core.StepExecutionListener#afterStep(StepExecution)
     */
    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        for (Iterator<StepExecutionListener> iterator = list.reverse(); iterator.hasNext();) {
            StepExecutionListener listener = iterator.next();
            ExitStatus close = listener.afterStep(stepExecution);
            stepExecution.setExitStatus(stepExecution.getExitStatus().and(close));
        }
        return stepExecution.getExitStatus();
    }

    /**
     * Call the registered listeners in order, respecting and prioritizing those
     * that implement {@link Ordered}.
     * @see org.springframework.batch.core.StepExecutionListener#beforeStep(StepExecution)
     */
    @Override
    public void beforeStep(StepExecution stepExecution) {
        for (Iterator<StepExecutionListener> iterator = list.iterator(); iterator.hasNext();) {
            StepExecutionListener listener = iterator.next();
            listener.beforeStep(stepExecution);
        }
    }
}